//
//  QRcodeScan.swift
//  QRscan
//
//  Created by jws on 2017/12/21.
//  Copyright © 2017年 jws. All rights reserved.
//

import UIKit
import AVFoundation

class QRcodeScaner: UIViewController,AVCaptureMetadataOutputObjectsDelegate{
    var scanRectView:UIView!
    
    let scanLine = UIImageView()
    
    private var device:AVCaptureDevice!
    private var input:AVCaptureInput!
    private var output:AVCaptureMetadataOutput!
    private var session:AVCaptureSession!
    private var preview:AVCaptureVideoPreviewLayer!
    
    var timer = Timer()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.initDevice()

        self.navigationController?.navigationBar.barTintColor?.withAlphaComponent(0.1)
        self.navigationController?.navigationBar.tintColor = UIColor.white

        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    }
    override func viewWillDisappear(_ animated: Bool) {
        //计时器销毁
        self.timer.fireDate = Date.distantFuture
        self.timer.invalidate()
        _ = self.navigationController?.popViewController(animated: true)
    }
    func initDevice(){
        // Device
        do{
            self.device = AVCaptureDevice.default(for: AVMediaType.video)
            
            self.input = try AVCaptureDeviceInput(device: device)
            
            self.output = AVCaptureMetadataOutput()
            output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            
            self.session = AVCaptureSession()
            if UIScreen.main.bounds.size.height<500 {
                self.session.sessionPreset = AVCaptureSession.Preset.vga640x480
            }else{
                self.session.sessionPreset = AVCaptureSession.Preset.high
            }
            
            if self.session.canAddInput(self.input){
                self.session.addInput(self.input)
            }else{
                print("Session Add Input 初始化失败")
                return
            }
            
            if self.session.canAddOutput(self.output){
                self.session.addOutput(self.output)
            }else{
                print("Session Add Output 初始化失败")
                return
            }
            
            self.output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
            
            //计算中间可探测区域
            let windowSize = UIScreen.main.bounds.size
            let scanSize = CGSize(width:windowSize.width*3/4, height:windowSize.width*3/4)
            var scanRect = CGRect(x:(windowSize.width-scanSize.width)/2,
                                  y:(windowSize.height-scanSize.height)/2,
                                  width:scanSize.width, height:scanSize.height)
            //计算rectOfInterest 注意x,y交换位置
            scanRect = CGRect(x:scanRect.origin.y/windowSize.height,
                              y:scanRect.origin.x/windowSize.width,
                              width:scanRect.size.height/windowSize.height,
                              height:scanRect.size.width/windowSize.width);
            //设置可探测区域
            self.output.rectOfInterest = scanRect
            
            self.preview = AVCaptureVideoPreviewLayer(session:self.session)
            self.preview.videoGravity = AVLayerVideoGravity.resizeAspectFill
            self.preview.frame = UIScreen.main.bounds
            self.view.layer.insertSublayer(self.preview, at:0)
            
            //添加中间的探测区域绿框
            self.scanRectView = UIView();
            self.view.addSubview(self.scanRectView)
            self.scanRectView.frame = CGRect(x:0, y:0, width:scanSize.width,
                                             height:scanSize.height);
            self.scanRectView.center = CGPoint( x:UIScreen.main.bounds.midX,
                                                y:UIScreen.main.bounds.midY)
            self.scanRectView.layer.borderColor = UIColor.green.cgColor
            self.scanRectView.layer.borderWidth = 2
            
            //设置扫描线
            scanLine.frame = CGRect(x: 0, y: 0, width: self.scanRectView.frame.size.width, height: 5)
            scanLine.image = UIImage(named: "ScanLine")
            //添加扫描线图层
            self.scanRectView.addSubview(scanLine)
            timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(moveScannerLayer(_:)), userInfo: nil, repeats: true)
            
            //开始捕获
            self.session.startRunning()
        }catch _ {
            //打印错误消息
            let alertController = UIAlertController(title: "提醒",
                                                    message: "请在iPhone的\"设置-隐私-相机\"选项中,允许本程序访问您的相机",
                                                    preferredStyle: .alert)
            let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
            alertController.addAction(cancelAction)
            self.present(alertController, animated: true, completion: nil)
        }
    }
    
    @objc func moveScannerLayer(_ timer : Timer) {
        scanLine.frame = CGRect(x: 0, y: 0, width: self.scanRectView.frame.size.width, height: 12)
        UIView.animate(withDuration: 2) {
            self.scanLine.frame = CGRect(x: self.scanLine.frame.origin.x, y: self.scanLine.frame.origin.y + self.scanRectView.frame.size.height - 10, width: self.scanLine.frame.size.width, height: self.scanLine.frame.size.height)
        }
    }
    func metadataOutput(_ output: AVCaptureMetadataOutput,didOutput metadataObjects: [AVMetadataObject],from connection: AVCaptureConnection) {
        var stringValue: String?
        if metadataObjects.count > 0 {
            // 停止扫描
            self.timer.fireDate = Date.distantFuture  //计时器暂停
            self.session.stopRunning()
            
            if let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject{
                stringValue = metadataObject.stringValue
            }
            if stringValue != nil {
                print(stringValue!)
                let alertController = UIAlertController(title: stringValue!,
                                                        message: nil, preferredStyle: .alert)
                //显示提示框
                self.present(alertController, animated: true, completion: nil)
                //两秒钟后自动消失
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.7) {
                    self.presentedViewController?.dismiss(animated: false, completion: {() -> Void in
                        DispatchQueue.main.async {
                            self.session.startRunning()
                            self.timer.fireDate = Date.distantPast  //计时器继续
                        }
                    })
                }
            }
        }
    }
    
    deinit {
        let time = DispatchTime.now()
        print("\(time): QRcodeScaner Close!")
    }

}
